Static Decorator

Circle circle{3};
ColoredShape redCircle{circle, "red"};
redCircle.resize(2); // compile error, resize는 Circle에 정의
// ColoreShape는 Shape만 상속함
데커레이션된 객체의 멤버 함수와 필드에는 모두 접근할 수 있어야 하는 경우,
템플릿과 상속(믹스인 상속)을 이용해서 이를 구현한다.

Mix-In 상속: 템플릿 인자로 받은 클래스를 부모 클래스로 지정하는 방식
template <typename T>
struct ColoredShape: T{
static_assert(is_base_of<Shape, T>::value, "Template arguement must be a Shape");
string color;
string str() const override {
ostringstream oss;
oss<<T::str()<<" has the color "<<color;
return oss.str();
}
};
// 사용(TransparentShape는 생략)
ColoredShape<TransparentShape<Square>> square{"blue"};
square.size=2;
square.transparency=0.5;
cout<<square.str();
square.resize(3);
// square를 통해 어떤 멤버든 접근 가능
제네릭 파라미터 팩을 이용한 생성자 호출 자동화
template <typename T>
struct TransparentShape: T{
uint8_t transparency;
// 상위 클래스(T)로 파라미터 팩을 전달
template <typename ...Args>
TransparentShape(const uint8_t transparency, Args... args): T(std::forward<Args>(args)...), transparency{transparency} {}
// ...
}; // ColoredShape는 생략
// 사용
ColoredShape2<TransparentShape2<Square>> sq={"red", 51, 5};
cout<<sq.str()<<endl;